package com.hzgj.bcl.soa.cicada.handle;

import com.hzgj.bcl.soa.cicada.sender.CicadaSender;

import java.io.IOException;

import io.netty.channel.Channel;

public final class SocketProcessor extends Processor {

    public SocketProcessor(CicadaSender cicadaSender) {
        super(cicadaSender);
    }

    private void finishUpdate(final ResponseFuture<?> future, Channel channel) throws IOException {
        future.detachChannel();
        markAsDone(future, channel);
    }

    private void markAsDone(ResponseFuture<?> future, final Channel channel) {

        future.cancelTimeouts();

        // We need to make sure everything is OK before adding the
        // connection back to the pool.
//        cicadaSender.releaseChannel(channel);
        cicadaSender.releaseChannel(channel, future.getPoolKey());

        try {
            future.done();
        } catch (Throwable t) {
            // Never propagate exception once we know we are done.
            logger.debug(t.getMessage(), t);
        }

    }


    @Override
    public void handle(final Channel channel, final ResponseFuture<Object> future, final Object e) throws Exception {

        future.touch();
        // future is already done because of an exception or a timeout
        if (future.isDone()) {
            cicadaSender.releaseChannel(channel, future.getPoolKey());
            return;
        }
        try {
            future.updateContent(e);
        } catch (Exception t) {
            try {
                cicadaSender.abort(future, t);
            } catch (Exception abortException) {
                logger.debug("Abort failed", abortException);
                throw t;
            }
        } finally {
            finishUpdate(future, channel);
        }
    }

    @Override
    public void onError(ResponseFuture<Object> future, Throwable error) {

    }

    @Override
    public void onClose(ResponseFuture<Object> future) {
    }
}
